package com.atugigu.controller;


import org.apache.commons.io.IOUtils;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.multipart.MultipartFile;


import javax.servlet.ServletContext;
import javax.servlet.http.HttpSession;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;


/**
 * @author ：HB
 * @date ：Created in 2020/10/29 10:04
 * @description： 文件上传下载测试
 * <p>
 * springmvc底层封装了fileupload
 * <p>
 * 文件上传客户端三要素：
 * 1. 表单项type="file"
 * 2. 表单提交的方式是post
 * 3. 表单的enctype属性是多部份表单的形式 ，以及enctype="multipart/form-data"
 * <p>
 * 文件上传原理：
 * 当form表单修改为多部分表单时，request.getParameter()将失效。
 * enctype=“application/x-www-form-urlencoded”时，form表单的正文内容格式是：key=value&key=value&key=value
 * 当form表单的enctype取值为Mutilpart/form-data时，请求正文内容就变成多部分形式：
 * <p>
 * 单文件上传步骤：
 * 1. 导入fileupload和io坐标
 * 2. 配置文件上传解析器
 * 3. 编写文件上传代码
 */
@Controller
@RequestMapping("/user")
public class UserController5 {

    /**
     * http://localhost:8080/springmvc_day02_01_response/upload.jsp
     * @param username :表单中的名称name属性值
     * @param multipartFile： 表单中的文件name属性值
     * @return
     * getOriginalFilename()
     * transferTo()
     */
    @RequestMapping("/testUpLoad")
    public String testUpLoad(String username, MultipartFile multipartFile) throws IOException {

//        System.out.println("username = " + username);
//        System.out.println("multipartFile = " + multipartFile);
        //获得上传文件的名称 getOriginalFilename() 不要写成getName()
        String originalFilename = multipartFile.getOriginalFilename();
        //System.out.println("originalFilename = " + originalFilename);
        //transferTo 的意思就是将那个文件转移到那里
        multipartFile.transferTo(new File("D:\\upload\\"+originalFilename));
        return "success";
    }

    /**
     * 多文件上传
     * @param username
     * @param multipartFile:这个参数要和name属性的值一样 才能映射.多媒体文件
     *
     *   文件1<input type="file" name="multipartFile"><br/>
     *   文件2<input type="file" name="multipartFile"><br/>
     * @return
     * @throws IOException
     */
    @RequestMapping("/testUpLoad2")
    public String testUpLoad2(String username, MultipartFile[] multipartFile) throws IOException {
        for (MultipartFile file : multipartFile) {
            String originalFilename = file.getOriginalFilename();
            file.transferTo(new File("D:\\upload\\"+originalFilename));
        }
        return "success";
    }

    /**
     * 实现图片下载功能
     * @param fileName
     * @param session
     * @return
     * @throws IOException
     */
    @RequestMapping("/testDownLoad")
    public ResponseEntity<byte[]> download(String fileName, HttpSession session) throws IOException {
        ServletContext servletContext = session.getServletContext();
        System.out.println("servletContext = " + servletContext);
        //将文件转成字节流
        // ‘/upload’表示在webapp下的upload目录下
        InputStream resourceAsStream = servletContext.getResourceAsStream("/upload/" + fileName);
        //将字节流转成字节数组
        byte[] bytes = IOUtils.toByteArray(resourceAsStream);
        //响应头
        HttpHeaders headers = new HttpHeaders();
        //设置响应头,Content-Disposition 告诉浏览器,收到的数据,怎么处理
        /**
         * 第一个参数是 : 响应体 <br/>
         * 第二个参数是 : 响应头 <br/>
         * 第三个参数是 : 响应行( 响应状态码 )
         */
        headers.add("Content-Disposition","attachement; filename=" + fileName);
        //HttpStatus.OK 200 服务器状态
        // 2 将下载的文件内容保存到,响应体中
        return new ResponseEntity<>(bytes,headers, HttpStatus.OK);

    }
}
